package com.lims.身份证;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;

/**
 * @author WenHua Huang
 * @date 2021/11/16 11:16
 */
public class IdCardUtils {

    /**
     * 省、自治区、直辖市代码
     */
    private static final String[] PROVINCES = {"11", "12", "13", "14", "15", "21", "22", "23", "31", "32", "33", "34", "35", "36", "37", "41", "42", "43",
            "44", "45", "46", "50", "51", "52", "53", "54", "61", "62", "63", "64", "65", "71", "81", "82"};

    /**
     * 地级市、盟、自治州代码
     */
    private static final String[] CITYS = {"01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "21", "22", "23", "24", "25", "26", "27", "28"};

    /**
     * 县、县级市、区代码
     */
    private static final String[] COUNTYS = {"01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "21", "22", "23", "24", "25", "26", "27", "28",
            "29", "30", "31", "32", "33", "34", "35", "36", "37", "38"};


    /**
     * 随机生成出生年月
     *
     * @return str
     */
    public static String getRandomBirthDate() {
        SimpleDateFormat dft = new SimpleDateFormat(DateFormatConstants.YEAR_MONTH_DAY);
        Date beginDate = new Date();
        Calendar date = Calendar.getInstance();
        date.setTime(beginDate);
        date.set(Calendar.DATE, date.get(Calendar.DATE) - new Random().nextInt(365 * 100));
        return dft.format(date.getTime());
    }

    /**
     * 替换身份证中的日期为当前日期
     *
     * @param idCard 真实身份证
     * @return 虚拟的身份证
     */
    public static String replaceCurrentIdCard(String idCard) {
        StringBuilder fakeIdCard = new StringBuilder(idCard);
        fakeIdCard.replace(6, 14, getCurrentDate());
        return fakeIdCard.toString();
    }

    /**
     * 替换身份证中的日期为当前日期且更换最后一位校验码
     *
     * @param idCard 18位身份证号
     * @return 生成的身份证号
     */
    public static String getIdCardByCurrentDate(String idCard) {
        StringBuilder fakeIdCard = new StringBuilder(idCard);
        fakeIdCard.replace(6, 14, getCurrentDate());
        fakeIdCard.replace(idCard.length() - 1, idCard.length(), String.valueOf(IdCardGenerator.getCalcTrailingNumber(fakeIdCard)));
        return fakeIdCard.toString();
    }

    /**
     * 替换身份证中的日期为随机日期
     *
     * @param idCard 真实身份证
     * @return 虚拟的身份证
     */
    public static String replaceRandomIdCard(String idCard) {
        StringBuilder fakeIdCard = new StringBuilder(idCard);
        fakeIdCard.replace(6, 14, getRandomBirthDate());
        return fakeIdCard.toString();
    }

    /**
     * 替换身份证中的日期为随机日期且更换最后一位校验码
     *
     * @param idCard 18位身份证号
     * @return 生成的身份证号
     */
    public static String getIdCardByRandomDate(String idCard) {
        StringBuilder fakeIdCard = new StringBuilder(idCard);
        fakeIdCard.replace(6, 14, getRandomBirthDate());
        fakeIdCard.replace(idCard.length() - 1, idCard.length(), String.valueOf(IdCardGenerator.getCalcTrailingNumber(fakeIdCard)));
        return fakeIdCard.toString();
    }

    /**
     * 获取当前日期的年月日Str
     *
     * @return str
     */
    public static String getCurrentDate() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        Date currentDate = new Date();
        return dateFormat.format(currentDate);
    }

    /**
     * 生成一个随机身份证号
     *
     * @return 18位身份证号
     */
    public static String getRandomIdCard() {
        StringBuilder identityNo = new StringBuilder();
        // 随机生成省、自治区、直辖市代码 1-2
        identityNo.append(PROVINCES[new Random().nextInt(PROVINCES.length - 1)]);
        // 随机生成地级市、盟、自治州代码 3-4
        identityNo.append(CITYS[new Random().nextInt(CITYS.length - 1)]);
        // 随机生成县、县级市、区代码 5-6
        identityNo.append(COUNTYS[new Random().nextInt(COUNTYS.length - 1)]);
        // 随机生成出生年月 7-14
        identityNo.append(getRandomBirthDate());
        // 随机生成顺序号 15-17
        identityNo.append(new Random().nextInt(899) + 100);
        // 生成校验码 18
        identityNo.append(IdCardGenerator.getCalcTrailingNumber(identityNo));
        return identityNo.toString();
    }

    /**
     * 计算校验码
     *
     * @param cardId 前十七位身份证号
     * @return 校验码
     */
    @Deprecated
    private static char getVerifyCode(StringBuilder cardId) {
        char[] valCodeArr = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
        int[] wi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
        int tmp = 0;
        for (int i = 0; i < wi.length; i++) {
            tmp += Integer.parseInt(String.valueOf(cardId.charAt(i))) * wi[i];
        }
        return valCodeArr[tmp % 11];
    }

}
